package com.xix.canal.client.writer.mysql.monitor;

import com.xixi.canal.client.DataWriter;
import com.xixi.canal.client.support.WriterConfig;
import com.xixi.canal.client.support.YmlConfigLoader;
import com.xixi.canal.client.util.StringUtil;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Properties;

public class MysqlConfigMonitor {

    private static final Logger logger = LoggerFactory.getLogger(MysqlConfigMonitor.class);

    private FileAlterationMonitor fileMonitor;

    private Properties properties;

    private String destination;

    private WriterConfig writerConfig;

    private DataWriter dataWriter;

    private volatile boolean running = false;

    public MysqlConfigMonitor(DataWriter dataWriter,
                              Properties properties,
                              String destination,
                              WriterConfig writerConfig) {
        this.dataWriter = dataWriter;
        this.properties = properties;
        this.destination = destination;
        this.writerConfig = writerConfig;
    }

    public void init() {
        if (running) return;
        File confDir = StringUtil.getConfDirPath(writerConfig.getConfDir(), destination);
        File tabaleFile = new File(confDir, "mysql");
        try {
            FileAlterationObserver observer = new FileAlterationObserver(tabaleFile,
                    FileFilterUtils.and(FileFilterUtils.fileFileFilter(),
                            FileFilterUtils.suffixFileFilter("yml")));
            FileListener listener = new FileListener();
            observer.addListener(listener);
            fileMonitor = new FileAlterationMonitor(3000, observer);
            fileMonitor.start();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        running = true;
    }

    public void destroy() {
        try {
            running = false;
            fileMonitor.stop();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private class FileListener extends FileAlterationListenerAdaptor {

        @Override
        public void onFileChange(File file) {
            super.onFileChange(file);
            try {

                YmlConfigLoader.checkYaml(file);

                synchronized (dataWriter) {
                    dataWriter.destroy();

                    dataWriter.init(destination, writerConfig, properties);
                }
                logger.info("## mysql  config reloaded.");
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }
}
